package com.prs.crm.action.hr;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.courser.struts.BaseAction;
import org.courser.ui.PaginationSupport;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.prs.crm.annotation.Clew;
import com.prs.crm.context.AppContext;
import com.prs.crm.context.Constrains;
import com.prs.crm.context.DataBuilder;
import com.prs.crm.context.PersonPayroll;
import com.prs.crm.context.ToolKits;
import com.prs.crm.domain.hr.Leave;
import com.prs.crm.domain.hr.Payroll;
import com.prs.crm.domain.hr.PayrollBill;
import com.prs.crm.domain.hr.PayrollKpi;
import com.prs.crm.domain.hr.Person;
import com.prs.crm.domain.hr.SalaryFloatItem;
import com.prs.crm.domain.hr.SalaryItem;
import com.prs.crm.service.hr.LeaveService;
import com.prs.crm.service.hr.PayrollBillService;
import com.prs.crm.service.hr.PayrollKpiService;
import com.prs.crm.service.hr.PayrollRemarkService;
import com.prs.crm.service.hr.PayrollService;
import com.prs.crm.service.hr.PersonService;
import com.prs.crm.service.hr.SalaryFloatItemService;
import com.prs.crm.service.hr.SalaryItemService;

public class PayrollAction extends BaseAction {
	
	private static final long serialVersionUID = 1L;
	
	private Payroll payroll;
	private Person person;
	private PayrollBill payrollBill;
	private PayrollKpi payrollKpi;

	private PayrollService payrollService;
	private PersonService personService;
	private PayrollBillService payrollBillService;
	private PayrollRemarkService payrollRemarkService;
	private SalaryFloatItemService salaryFloatItemService;
	private LeaveService leaveService;
	private SalaryItemService salaryItemService;
	private PayrollKpiService payrollKpiService;

	private PaginationSupport pagination;
	private Integer[] ids;

	private List<SalaryFloatItem> salaryFloatItems;
	private Collection<SalaryItem> salaryItems;
	private List<PayrollBill> currentPayrollBills;
	private Collection<Person> payrollPersons;
	private Collection<Leave> leaves;
	private Collection<Integer> years;
	private Collection<Integer> months;	
	private Collection<PayrollBill> payrollBills;
	
	private String tallyStr;
	
	private String payrids;
	
	/**
	 * 薪酬设置的年份
	 */
	private Integer year;
	/**
	 * 薪酬设置的月份
	 */
	private Integer month;

	private String issuePersons;
	private String issuePersonNames;

	private Integer[] items;
	private String[] num;
	
	/**
	 * 增项总计
	 */
	private double increaseValue;
	/**
	 * 减项总计
	 */
	private double reduceValue;
	/**
	 * 实发总计
	 */
	private double authenticValue;
	
	private String fullTimeStr;
	private Collection<PersonPayroll> personPayrolls;
	private Collection<PayrollBill> payrollFormColumns;

	@Action("listPayroll")
	public String execute() {
		return SUCCESS;
	}
	@Action("listPayrollByYear")
	public String listPayrollByYear(){
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(Payroll.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		criteria.addOrder(Order.desc("recordTime"));
		if(payrids != null)
			criteria.add(Restrictions.in("issueYear", ToolKits.convertStringAryToIntAry(payrids.split(","))));
		this.setPagination(this.getPayrollService().listByPage(criteria,pagination));
		return SUCCESS;
	}
	
	@Action("listMyPayroll")
	public String listMyPayroll() {
		person = AppContext.getAccountContext().currentUser();
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(Payroll.class);
		criteria.add(Restrictions.in("id", payrollBillService.getPayrollIdsByPerson(person)));
		criteria.addOrder(Order.desc("recordTime"));
		pagination = this.getPaginationHelper().prepare(pagination);
		this.setPagination(this.getPayrollService().listByPage(criteria, pagination));
		return SUCCESS;
	}
	
	@Action("viewPayroll")
	public String viewPayroll() {
		reduceValue = 0;
		increaseValue = 0;
		List<PayrollBill> increaseItems = this.getPayrollBillService().getIncreaseItem(payroll);
		List<PayrollBill> reduceItems = this.getPayrollBillService().getReduceItem(payroll);
		
		for(PayrollBill bill : increaseItems) {
			increaseValue += bill.getValue();
		}
		for(PayrollBill bill : reduceItems) {
			reduceValue += bill.getValue();
		}
		
		authenticValue = increaseValue - reduceValue;
		
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(Person.class);
		criteria.add(Restrictions.in("id", this.getPayrollBillService()
				.findPersonIds(payroll)));
		payrollPersons = this.getPersonService().find(criteria);
		return SUCCESS;
	}
	
	@Action("viewPersonPayroll")
	public String viewPersonPayroll() {
		reduceValue = 0;
		increaseValue = 0;
		List<PayrollBill> increaseItems = this.getPayrollBillService().getIncreaseItem(payroll,person);
		List<PayrollBill> reduceItems = this.getPayrollBillService().getReduceItem(payroll,person);
		this.leaves = this.getLeaveService().getLeavesByPersonInMonth(person, payroll.getIssueYear(), payroll.getIssueMonth());
		
		for(PayrollBill bill : increaseItems) {
			increaseValue += bill.getValue();
		}
		for(PayrollBill bill : reduceItems) {
			reduceValue += bill.getValue();
		}
		
		authenticValue = increaseValue - reduceValue;
		
		this.currentPayrollBills = this.getPayrollBillService()
		.getCurrentPayrollBill(person, payroll);
		return SUCCESS;
	}

	@Action("listEditPayroll")
	public String listEditPayroll() {
		return SUCCESS;
	}
	@Action("listEditPayrollByYear")
	public String listEditPayrollByYear(){
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				Payroll.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		criteria.add(Restrictions.eq("state", Constrains.PAYROLL_EDIT));
		if(payrids != null)
			criteria.add(Restrictions.in("issueYear", ToolKits.convertStringAryToIntAry(payrids.split(","))));
		this.setPagination(this.getPayrollService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}

	@Action("editPayroll")
	public String edit() {
		Calendar c = Calendar.getInstance();
		c.setTime(new java.util.Date());
		this.setMonths(DataBuilder.buildMonthArea());
		this.setYears(DataBuilder.buildYearArea(2, 10));
		if (year == null) {
			this.setYear(c.get(Calendar.YEAR));
		}
		if (month == null) {
			this.setMonth(c.get(Calendar.MONTH));
		}
		
		salaryFloatItems = this.getSalaryFloatItemService().getAllSalaryFloatItem();
		salaryItems = this.getSalaryItemService().getAllSalaryItems();
		return SUCCESS;
	}

	@Clew(results = { "success" })
	@Action(value = "savePayroll", results = { @Result(name = "success", type = "redirect", location = "editPayroll"),
			@Result(name="error",type="chain",location="editPayroll")})
	public String savePayroll() {
		
		if(!ToolKits.isNumeric(fullTimeStr)) {
			this.addActionError("全勤天数应为数字");
			return ERROR;
		}
		if(!ToolKits.isNumeric(this.tallyStr)) {
			this.addActionError("考核单位金额应为数字");
			return ERROR;
		}
		if(issuePersonNames.equals("")){
			this.addActionError("发放对象不能为空");
			return ERROR;
		}
		payroll.setIssueMonth(month);
		payroll.setIssueYear(year);
		payroll.setFullTime(Double.valueOf(fullTimeStr));		
		
		payrollKpi.setTally(Double.valueOf(tallyStr));
		this.getPayrollService().savePayroll(payroll, issuePersons,payrollKpi);
		this.setPrompt("创建工资表成功");
		return SUCCESS;
	}

	@Action("checkPayroll")
	public String checkPayroll() {
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				Person.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		criteria.add(Restrictions.in("id", this.getPayrollBillService()
				.findPersonIds(payroll)));
		this.setPagination(this.getPersonService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}
	
	@Clew(results={"success"})
	@Action(value="submitPayroll",results={@Result(name="success",type="redirect",location="listEditPayroll")})
	public String submitPayroll() {
		this.setPrompt("工资单提交成功");
		payroll.setState(Constrains.PAYROLL_ISSUE);
		this.getPayrollService().save(payroll);
		return SUCCESS;
	}

	@Action("editCheckPayroll")
	public String editCheckPayroll() {
		this.currentPayrollBills = this.getPayrollBillService()
				.getCurrentPayrollBill(person, payroll);
		this.leaves = this.getLeaveService().getLeavesByPersonInMonth(person, payroll.getIssueYear(), payroll.getIssueMonth());
		return SUCCESS;
	}

	@Clew(results = { "success" })
	@Action(value = "submitPersonPayroll", results = { @Result(name = "success", type = "redirect", location = "checkPayroll?payroll=${payroll.id}") })
	public String submitPersonPayroll() {
		this.setPrompt("设置人员薪酬成功");
		int i = 0;
		for (Integer itemid : items) {
			PayrollBill bill = this.getPayrollBillService().get(itemid);
			bill.setValue(Double.parseDouble(num[i++]));
			bill.setState(Constrains.PAYROLL_ISSUE);
			this.getPayrollBillService().save(bill);
		}
		return SUCCESS;
	}
	
	@Action("editPayrollForm")
	public String editPayrollForm() {
		payrollBills = this.getPayrollBillService().getPayrollBillByPayroll(payroll);
		Collection<Integer> personIds = this.getPayrollBillService().findPersonIds(payroll);
		if(this.getPayrollFormColumns() == null) {
			this.setPayrollFormColumns(new ArrayList<PayrollBill>());
		}
		
		int count = 0;
		for(Integer id : personIds) {
			PersonPayroll roll = new PersonPayroll();
			roll.setId(id);
			roll.setPerson(this.getPersonService().get(id));
			for(PayrollBill bill : payrollBills) {
				if(bill.getPerson().getId().intValue() == id.intValue()) {
					roll.addPayrollBill(bill);
					
					if(count == 0) {
						this.getPayrollFormColumns().add(bill);
					}
				}
			}
			if(this.getPersonPayrolls() == null) {
				this.setPersonPayrolls(new ArrayList<PersonPayroll>());
			}
			this.getPersonPayrolls().add(roll);
			count ++;
		}
		return SUCCESS;
	}
	
	@Clew(results={"success"})
	@Action(value="submitPayrollForm",results={@Result(name="success",type="redirect",location="checkPayroll?payroll=${payroll.id}"),
			@Result(name="error",type="chain",location="editPayrollForm")})
	public String submitPayrollForm() {
		int i = 0;
		for(Integer id : items) {
			PayrollBill bill = this.getPayrollBillService().get(id);
			if(!ToolKits.isNumeric(num[i])) {
				this.addActionError("金额应为数字型");
				return ERROR;
			}
			bill.setValue(Double.parseDouble(num[i]));
			bill.setState(Constrains.PAYROLL_ISSUE);
			this.getPayrollBillService().save(bill);
			i++;
		}
		this.setPrompt("提交工资单成功");
		return SUCCESS;
	}

	public Payroll getPayroll() {
		return payroll;
	}

	public void setPayroll(Payroll payroll) {
		this.payroll = payroll;
	}

	public PayrollService getPayrollService() {
		return payrollService;
	}

	public void setPayrollService(PayrollService payrollService) {
		this.payrollService = payrollService;
	}

	public PaginationSupport getPagination() {
		return pagination;
	}

	public void setPagination(PaginationSupport pagination) {
		this.pagination = pagination;
	}

	public Integer[] getIds() {
		return ids;
	}

	public void setIds(Integer[] ids) {
		this.ids = ids;
	}

	public PersonService getPersonService() {
		return personService;
	}

	public void setPersonService(PersonService personService) {
		this.personService = personService;
	}

	public PayrollBillService getPayrollBillService() {
		return payrollBillService;
	}

	public void setPayrollBillService(PayrollBillService payrollBillService) {
		this.payrollBillService = payrollBillService;
	}

	public PayrollRemarkService getPayrollRemarkService() {
		return payrollRemarkService;
	}

	public void setPayrollRemarkService(
			PayrollRemarkService payrollRemarkService) {
		this.payrollRemarkService = payrollRemarkService;
	}

	public void setSalaryFloatItemService(
			SalaryFloatItemService salaryFloatItemService) {
		this.salaryFloatItemService = salaryFloatItemService;
	}

	public SalaryFloatItemService getSalaryFloatItemService() {
		return salaryFloatItemService;
	}

	public void setSalaryFloatItems(List<SalaryFloatItem> salaryFloatItems) {
		this.salaryFloatItems = salaryFloatItems;
	}

	public List<SalaryFloatItem> getSalaryFloatItems() {
		return salaryFloatItems;
	}

	public Collection<Integer> getYears() {
		return years;
	}

	public void setYears(Collection<Integer> years) {
		this.years = years;
	}

	public double getIncreaseValue() {
		return increaseValue;
	}

	public void setIncreaseValue(double increaseValue) {
		this.increaseValue = increaseValue;
	}

	public double getReduceValue() {
		return reduceValue;
	}

	public void setReduceValue(double reduceValue) {
		this.reduceValue = reduceValue;
	}

	public double getAuthenticValue() {
		return authenticValue;
	}

	public void setAuthenticValue(double authenticValue) {
		this.authenticValue = authenticValue;
	}

	public Collection<Integer> getMonths() {
		return months;
	}

	public void setMonths(Collection<Integer> months) {
		this.months = months;
	}

	public Integer getYear() {
		return year;
	}

	public Integer[] getItems() {
		return items;
	}

	public void setItems(Integer[] items) {
		this.items = items;
	}

	public String[] getNum() {
		return num;
	}

	public void setNum(String[] num) {
		this.num = num;
	}

	public void setYear(Integer year) {
		this.year = year;
	}

	public Integer getMonth() {
		return month;
	}

	public String getIssuePersons() {
		return issuePersons;
	}

	public void setIssuePersons(String issuePersons) {
		this.issuePersons = issuePersons;
	}

	public String getIssuePersonNames() {
		return issuePersonNames;
	}

	public void setIssuePersonNames(String issuePersonNames) {
		this.issuePersonNames = issuePersonNames;
	}

	public void setMonth(Integer month) {
		this.month = month;
	}

	public void setPayrollBill(PayrollBill payrollBill) {
		this.payrollBill = payrollBill;
	}

	public PayrollBill getPayrollBill() {
		return payrollBill;
	}

	public void setPerson(Person person) {
		this.person = person;
	}

	public Person getPerson() {
		return person;
	}

	public void setPayrollBills(Collection<PayrollBill> payrollBills) {
		this.payrollBills = payrollBills;
	}

	public Collection<PayrollBill> getPayrollBills() {
		return payrollBills;
	}

	public void setCurrentPayrollBills(List<PayrollBill> currentPayrollBills) {
		this.currentPayrollBills = currentPayrollBills;
	}

	public List<PayrollBill> getCurrentPayrollBills() {
		return currentPayrollBills;
	}

	public void setPayrollPersons(Collection<Person> payrollPersons) {
		this.payrollPersons = payrollPersons;
	}

	public Collection<Person> getPayrollPersons() {
		return payrollPersons;
	}

	public void setLeaveService(LeaveService leaveService) {
		this.leaveService = leaveService;
	}

	public LeaveService getLeaveService() {
		return leaveService;
	}

	public void setLeaves(Collection<Leave> leaves) {
		this.leaves = leaves;
	}

	public Collection<Leave> getLeaves() {
		return leaves;
	}

	public void setFullTimeStr(String fullTimeStr) {
		this.fullTimeStr = fullTimeStr;
	}

	public String getFullTimeStr() {
		return fullTimeStr;
	}

	public void setPersonPayrolls(Collection<PersonPayroll> personPayrolls) {
		this.personPayrolls = personPayrolls;
	}

	public Collection<PersonPayroll> getPersonPayrolls() {
		return personPayrolls;
	}

	public void setPayrollFormColumns(Collection<PayrollBill> payrollFormColumns) {
		this.payrollFormColumns = payrollFormColumns;
	}

	public Collection<PayrollBill> getPayrollFormColumns() {
		return payrollFormColumns;
	}

	public void setSalaryItems(Collection<SalaryItem> salaryItems) {
		this.salaryItems = salaryItems;
	}

	public Collection<SalaryItem> getSalaryItems() {
		return salaryItems;
	}

	public void setSalaryItemService(SalaryItemService salaryItemService) {
		this.salaryItemService = salaryItemService;
	}

	public SalaryItemService getSalaryItemService() {
		return salaryItemService;
	}

	public void setPayrollKpi(PayrollKpi payrollKpi) {
		this.payrollKpi = payrollKpi;
	}

	public PayrollKpi getPayrollKpi() {
		return payrollKpi;
	}

	public void setPayrollKpiService(PayrollKpiService payrollKpiService) {
		this.payrollKpiService = payrollKpiService;
	}

	public PayrollKpiService getPayrollKpiService() {
		return payrollKpiService;
	}

	public void setTallyStr(String tallyStr) {
		this.tallyStr = tallyStr;
	}

	public String getTallyStr() {
		return tallyStr;
	}

	public String getPayrids() {
		return payrids;
	}

	public void setPayrids(String payrids) {
		this.payrids = payrids;
	}
	
}
